package com.gc.cscott.verify.contest2012jan;

import com.gc.cscott.verify.JavaTaskOutputVerifier;
import com.gc.cscott.verify.OutputVerifier.VerifiedOutput;
import java.util.LinkedList;

/**
 *
 * @author User
 */
public class CheckZ3XML implements JavaTaskOutputVerifier  {

    public VerifiedOutput verify(String inputText, String outputText, String validationHintText) {
        final String inputTrim = inputText.trim();
        final String outputTrim = outputText.trim();
        if (inputTrim.length()!=outputTrim.length()){
            return VerifiedOutput.outputIsWrong("Wrong text length, extected: "+inputTrim.length()+", passed: "+outputTrim.length());
        } else {
            int diffs = 0;
            for(int i=0;i<inputTrim.length();i++){
                if (inputTrim.charAt(i)!=outputTrim.charAt(i)){
                    diffs+=1;
                }
            }
            if (diffs!=1){
                return VerifiedOutput.outputIsWrong("Wrong differences count: "+diffs+"("+inputTrim+"){"+outputTrim+"}");
            } else {
                final String error = checkXmlCorrectness(outputTrim);
                if (error!=null){
                    return VerifiedOutput.outputIsWrong(error);
                } else {
                    return VerifiedOutput.outputIsCorrect();
                }
            }
        }
    }

    private String checkXmlCorrectness(String outputTrim) {
        final LinkedList<String> stack = new LinkedList<String>();
        for(final String tagRaw:outputTrim.replace("<", "").replace(">"," ").split("\\s+")){
            final String tagTrim = tagRaw.trim();
            if (tagTrim.startsWith("/")){
                final String tag = tagTrim.substring(1);
                if (stack.isEmpty()){
                    return "stack is empty, expected: "+tag;
                } else if (stack.getLast().equals(tag)){
                    stack.removeLast();
                } else {
                    return "expected "+tag+" holds "+stack.getLast();
                }
            } else {
                stack.addLast(tagTrim);
            }
        }
        if (stack.isEmpty()){
            return null;
        } else {
            return "not closed tags: "+stack;
        }
    }

    public static void main(String[] args) {
        System.out.println(new CheckZ3XML().checkXmlCorrectness("<in><out></out></in>"));
    }

}
